#include "Brick.h"
#include "Level.h"

Brick::Brick(const sf::Sprite& sprite, properties props) : value(10), props(props), sprite(sprite), x(1)
{
    destroyed = false;
    dropsBonuses = false;
    w = sprite.GetGlobalBounds().Width;
    h = sprite.GetGlobalBounds().Height;
}

void Brick::draw(sf::RenderWindow* Window)
{
    if(!destroyed)
        Window->Draw(sprite);
}

float Brick::getX()
{
    return sprite.GetGlobalBounds().Left;
}

float Brick::getY()
{
    return sprite.GetGlobalBounds().Top;
}

void Brick::onHit(Level* level, Ball* ball)
{
    rm->playSound("killedBrick.wav");
    if(props.stone != true && !destroyed)
    {
        incrementTotalBricksShattered();
        if(!props.hitTwice)
        {
            if(props.pin)
            {
                sf::FloatRect ballrect;
                if(ball != NULL)
                    ballrect = ball->ballSprite.GetGlobalBounds();
                else
                    ballrect = sf::FloatRect(0,0,0,0);
                sf::FloatRect rect = sprite.GetGlobalBounds();
                if(ballrect.Width + ballrect.Left > rect.Left && ballrect.Left <  rect.Left + rect.Width && ballrect.Top > rect.Top - 2)
                {
                    ball->destroyed = true;
                    level->onBallMissed();

                }
                else
                {
                    points += value;
                    destroyed = true;
                    killedBricks++;
                    tPinBricks++;
                }
            }
            else
            {
                points += value;
                destroyed = true;
                killedBricks++;
                if(props.explosive)
                    explode(level);
                else
                    level->randomBonus(getX() + 20, getY());
            }
        }

        else
        {
            props.hitTwice = false;
            sprite.SetTexture(rm->getTexture("greenBrick2.png"));
        }
    }

}

void Brick::incrementTotalBricksShattered()
{
    if(props.hitTwice)
        tGreenBricks++;
    else if(props.explosive)
        tExploBricks++;
    else if(sprite.GetGlobalBounds().Width < 50)
        tMiniBricks++;
    else if(!props.pin)
        tNormalBricks++;
}

void Brick::update(Level* level)
{
    for(auto itr = level->balls.begin(); itr != level->balls.end(); itr++)
        if(collide((*itr)->ballSprite, sprite))
        {
            if(!(*itr)->acid || props.stone)
            {
                switch(side)
                {
                    case 0: (*itr)->dy = -abso((*itr)->dy);
                            break;
                    case 1: (*itr)->dx = abso((*itr)->dx);
                            break;
                    case 2: (*itr)->dy = abso((*itr)->dy);
                            break;
                    case 3: (*itr)->dx = -abso((*itr)->dx);
                            break;
                }
            }
            if(!props.stone)
                onHit(level, (*itr));
        }

    if(props.moving)
    {
        sf::FloatRect rect1 = sprite.GetGlobalBounds();
        if(rect1.Left < 0)
            x = abs(x);
        else if(rect1.Left+rect1.Width > 800)
            x = -abs(x);
        for(auto itr = level->bricks.begin(); itr != level->bricks.end(); itr++)
        {
            sf::FloatRect rect2 = (*itr)->sprite.GetGlobalBounds();
            if(rect1.Intersects(rect2) && (*itr) != this)
                x = -x;
        }
        sprite.Move(x, 0);
    }
}

void Brick::explode(Level* level)
{

    sf::FloatRect rect = sprite.GetGlobalBounds();
    level->addExplosion(rect.Left, rect.Top);
    rm->playSound("explosion.wav");
    sf::FloatRect explosionZone(rect.Left - 16, rect.Top - 16, rect.Width + 24, rect.Height + 24);
    for(auto itr = level->bricks.begin(); itr != level->bricks.end(); itr++)
    {
        if((*itr) != this)
        {
            if(explosionZone.Intersects((*itr)->sprite.GetGlobalBounds()))
                (*itr)->onHit(level, NULL);
        }
    }
}
